# encoding: utf-8

import os
import json
from pub.trans import TransBase, json2dict

from util.log import getLogger
logger = getLogger()

class RegCodeTrans(TransBase):
    """ 向服务端发送注册验证：
        {
            "type": "Register",
            "machine_id": "xxxxx",
        }
    """
    def __init__(self, rsa_crypto):
        super().__init__()

        # 通用属性
        self.crypto = rsa_crypto
        self.map_license = {}  # license: machine_id

    # def init_server(self, dir_pem):
    #     """ 如不存在pem，则生成密钥对 """
    #     if os.path.exists(dir_pem):
    #         self.crypto.load_keys(dir_pem)
    #     else:
    #         self.crypto.create_keys(dir_pem)

    # def init_client(self):
    #     """ 如不存在pem公钥，则向服务器请求公钥 """
    #     if os.path.exists(dir_pem):
    #         self.crypto.load_keys(dir_pem)
    #     else:
    #         self.ask_for_pubkey()

    ###########################################################################
    def reply(self, msg: bytes, sock1addr=None):
        # logger.debug("接收到消息：【{}】".format(msg))
        msg_head, msg_body = self.sock.msg_split(msg)

        if self.check_cmd(msg):
            dict_msg = json2dict(msg_body)
            if dict_msg["type"] == "Register":
                self.reply_register(dict_msg, sock1addr)
            # elif dict_msg["type"] == "PubKey":
            #     self.reply_pubkey(dict_msg, sock1addr)
            else:
                err = "Unkown command [{}]".format(msg)
                self.send_error(err.encode(), sock1addr)

        elif self.check_data(msg):
            pass

        else:
            err = "Unkown request [{}]".format(msg)
            self.send_error(err.encode(), sock1addr)

    def parse_reply(self, msg: bytes):
        # logger.debug("接收到回复：【{}】".format(msg))
        msg_head, msg_body = self.sock.msg_split(msg)

        if self.check_cmd(msg):
            dict_msg = json2dict(msg_body)
            if dict_msg["type"] == "Register":
                self.on_register(dict_msg)
            elif dict_msg["type"] == "PubKey":
                self.on_pubkey(dict_msg)
            else:
                print("未解析命令【{}】".format(msg))

        elif self.check_data(msg):
            pass

        else:
            logger.error("Fail to parse the message【{}】.".format(msg))

    def ask_for_pubkey(self):
        dict_msg = {
            "type": "PubKey"
        }
        self.send_cmd(dict_msg)

    def reply_pubkey(self, dict_msg, sock1addr):
        bytes_pubkey = self.crypto.get_pubkey()
        dict_msg["pubkey"] = bytes_pubkey
        self.send_cmd(dict_msg, sock1addr)

    def on_pubkey(self, dict_msg):
        bytes_pubkey = dict_msg["pubkey"]
        # 存储pubkey
        with open("./pem/public.pem", "wb") as fp:
            fp.write(bytes_pubkey)

    def register(self, license):
        import uuid
        machine_code = uuid.getnode()  # int

        dict_msg = {
            "type": "Register",
            "license": license,
            "machine_id": machine_code
        }
        self.send_cmd(dict_msg)

    def reply_register(self, dict_msg, sock1addr):
        license = dict_msg["license"]
        dict_msg_ret = {"type": "Register"}
        if license in self.map_license:
            dict_msg_ret["return"] = "false"
            dict_msg_ret["reason"] = "license【{}】已注册".format(license)
            self.send_cmd(dict_msg_ret, sock1addr)
        else:
            dict_msg_ret["return"] = "true"
            self.map_license[license] = dict_msg["machine_id"]
            certificate, signature = self._make_certificate(dict_msg)
            dict_msg_ret["certificate"] = certificate
            dict_msg_ret["signature"] = signature
            self.send_cmd(dict_msg_ret, sock1addr)

    def _make_certificate(self, dict_msg):
        """ return a text """
        # 查询license有效期，在此实现有效期认证逻辑...
        from datetime import date
        today = date.today()
        year = today.year + 1
        month = today.month + 2
        # day = today.day + 3
        deadline = today.replace(year, month)

        dict_info = {
            "license": dict_msg["license"],
            "machine": dict_msg["machine_id"],
            "deadline": deadline.isoformat()
        }
        certificate = json.dumps(dict_info)
        signature = self.crypto.sign(certificate).decode()
        return certificate, signature

    def on_register(self, dict_msg):
        if dict_msg["return"] == "false":
            reason = dict_msg["reason"]
            logger.info("注册失败 -->> {}".format(reason))
            return

        certificate = dict_msg["certificate"]
        signature = dict_msg["signature"]

        dir_ = "./tmp"
        path_certificate = os.path.join(dir_, "certificate.txt")
        if not os.path.exists(dir_):
            os.makedirs(dir_)
        with open(path_certificate, "w") as fp:
            lines = signature + "\n" + certificate
            fp.write(lines)

        logger.debug("已保存注册证书【{}】".format(path_certificate))
